// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// v [author] rhyme_lph
// i [email]  rhymelph@gmail.com
// Z [github] https://github.com/rhymelph

import 'dart:async';

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/user_profile_entity.dart';
import 'package:finance_app/src/http_service/http_login_service.dart';
import 'package:finance_app/src/http_service/http_user_service.dart';
import 'package:finance_app/src/mixin/validate_code_mixin.dart';
import 'package:finance_app/src/widgets/bottom_sheet/got_it_tip_bottom_sheet.dart';
import 'package:flutter/material.dart';
import 'package:local_auth/local_auth.dart';

class UpdateEmailProvider extends BaseProvider with ValidateCodeMixin {
  TextEditingController emailController = TextEditingController();
  FocusNode emailFocus = FocusNode();
  String countryCode = "+65";

  bool hasEmailError = false;

  bool enableGetOTP = false;

  int step = 0;

  String number;

  TextEditingController validateController = TextEditingController();
  FocusNode validateFocusNode = FocusNode();

  bool hasValidateError = false;

  bool enableUpdate = false;

  TextEditingController passwordController = TextEditingController();
  FocusNode passwordFocusNode = FocusNode();

  bool passwordError = false;

  bool enableVerify = false;

  @override
  void initState() {
    super.initState();
    validateController.addListener(_onUpdateValidateInput);
    emailController.addListener(_onUpdateRegisterInput);
    passwordController.addListener(_onUpdatePassword);
  }

  void onGetOTP() async {
    emailFocus.unfocus();
    // Routes.navigateTo(RouterGenProviders.systemDetectionPage);
    String emailNumber = emailController.text;
    if (emailNumber.length < 8) {
      hasEmailError = true;
      update();
      return;
    }
    int stepValue = 1;
    //是否开启指纹验证
    if (Config.biometricsEnable == true) {
      stepValue = 2;
      final data = await LocalAuthentication()
          .authenticate(localizedReason: S.current.please_touch_fingerprint);
      if (data == false) {
        return;
      }
    }
    //todo 缺少更改手机号的接口
    await post(HttpLoginService.changeEmailOtp(emailNumber),
        loadingTip: S.current.loading, onSuccess: (result) {
      step += stepValue;
      update();
      number = emailController.text;
    }, onError: (_, ____, __, ___) {
      hasEmailError = true;
      update();
    });
    resetTimer();
  }

  @override
  Future get dataFuture => null;

  void _onUpdateRegisterInput() {
    if (emailController.text.length > 0) {
      if (enableGetOTP == false) {
        enableGetOTP = true;
        update();
      }
    } else {
      if (enableGetOTP == true) {
        enableGetOTP = false;
        update();
      }
    }
  }

  void _onUpdateValidateInput() {
    if (validateController.text.length > 0) {
      if (enableUpdate == false) {
        enableUpdate = true;
        update();
      }
    } else {
      if (enableUpdate == true) {
        enableUpdate = false;
        update();
      }
    }
  }

  void _onUpdatePassword() {
    if (passwordController.text.length > 0) {
      if (enableVerify == false) {
        enableVerify = true;
        update();
      }
    } else {
      if (enableVerify == true) {
        enableVerify = false;
        update();
      }
    }
  }

  void onChangeCountryCode(value) {
    countryCode = value;
  }

  void onResentOTP() async {
    if (currentOTPExpireTimer > 0) {
      showToast(S.current.please_waiting);
      return;
    }
    final email = number;
    bool isSuccess = false;
    await post(HttpLoginService.changeOtp(countryCode, email),
        loadingTip: S.current.loading, onSuccess: (result) {
      isSuccess = true;
    });
    if (isSuccess) {
      hasValidateError = false;
      resetTimer();
      update();
    }
  }

  void onUpdate() async {
    final code = validateController.text;
    UserProfileEntity userProfileEntity;
    await post(
        HttpUserService.updateMyProfileEmail(
          emailController.text,
          code,
        ),
        autoHandler: AutoHandler.Toast,
        loadingTip: S.current.loading, onSuccess: (result) {
      userProfileEntity = getEntityFromResult<UserProfileEntity>(result);
    }, onError:
            (int statusCode, String msg, Object error, StackTrace stackTrace) {
      hasValidateError = true;
      update();
    });
    if (userProfileEntity != null) {
      obtainContext?.call((context) async {
        await showLoginDetailUpdateSuccessTipBottomSheet(context);
        RProvider.myProvider.globalMap[ConfigKey.userProfile] =
            userProfileEntity;
        final bioData = Config.biometricsData;
        bioData.account = Config.userProfile.email;
        bioData.countryCode = Config.userProfile.countryCode;
        Config.biometricsData = bioData;
        await RProvider.myProvider.updateGlobalMap();
        Navigator.of(context).pop();
      });
    }
  }

  void onVerify() {
    final password = Config.biometricsData?.password;
    if (password != passwordController.text) {
      passwordError = true;
      update();
      return;
    }
    step++;
    update();
  }
}
